home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
labyte.zip
/
LABYTE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-08
|
9KB
|
344 lines
/* ------------------------------------ */
/* -- Logical Answers Byte -- */
/* -- Our Real Good Memory Manager -- */
/* ------------------------------------ */
#include <alloc.h>
#include <stdlib.h>
#include <stdio.h>
#define LATRACE 1 /* Compile with LATRACE enabled */
/* To disable LATRACE, Comment this statement */
#include <LAByte.h>
void *MemAnchor = NULL; /* First storage chain pointer */
TRACETBL *TraceTbl = NULL; /* Function trace table */
char far *mem_getmain(char *Mod, int Line, char Funct, char Use, int Len)
{
char far *Area, *Work;
unsigned long C, W;
MEMTBL *MemBlock, *MemWork;
trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
C = farcoreleft();
W = Len + 9;
if (!(W < C))
return(NULL);
Area = farmalloc(W);
memset(Area, NULL, W);
memcpy(Area, "^MH^", MEMHDRLEN);
Work = Area + Len + MEMHDRLEN;
memcpy(Work, "^MT^", MEMHDRLEN);
Area = Area + MEMHDRLEN;
MemBlock = malloc(sizeof(MEMTBL));
MemBlock->MemOK = 0;
strcpy(MemBlock->MemMod, Mod);
MemBlock->MemLine = Line;
MemBlock->MemFun = Funct;
MemBlock->MemUse = Use;
MemBlock->MemLen = Len;
MemBlock->MemAddr = Area;
MemBlock->MemNext = MemAnchor;
MemBlock->MemPrev = NULL;
MemWork = MemAnchor;
MemWork->MemPrev = MemBlock;
MemAnchor = MemBlock;
return(Area);
}
int mem_freemain(char *Mod, int Line, char far *Area)
{
char far *Work;
MEMTBL *MemBlock, *MemWork;
trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
MemBlock = MemAnchor;
if (MemBlock == NULL)
{
mem_cancel(Line, Mod, 1, MemBlock, Area);
return(-2);
}
for(;;)
{
if (MemBlock->MemAddr == Area)
break;
if (MemBlock->MemNext == NULL)
{
mem_cancel(Line, Mod, 2, MemBlock, Area);
return(-2);
}
MemBlock = MemBlock->MemNext;
}
MemWork = MemBlock->MemNext;
if (MemWork != NULL)
{
if (MemWork->MemPrev != MemBlock)
{
mem_cancel(Line, Mod, 3, MemWork, Area);
return(-2);
}
}
MemWork = MemBlock->MemPrev;
if (MemWork != NULL)
{
if (MemWork->MemNext != MemBlock)
{
mem_cancel(Line, Mod, 4, MemWork, Area);
return(-2);
}
}
Work = MemBlock->MemAddr;
Work = Work - MEMHDRLEN;
if (memcmp(Work, "^MH^", MEMHDRLEN) != 0)
{
mem_cancel(Line, Mod, 5, MemBlock, Area);
return(2);
}
Work = MemBlock->MemAddr;
Work = Work + MemBlock->MemLen;
if (memcmp(Work, "^MT^", MEMHDRLEN) != 0)
{
mem_cancel(Line, Mod, 6, MemBlock, Area);
return(-2);
}
MemWork = MemBlock->MemNext;
if (MemWork != NULL)
MemWork->MemPrev = MemBlock->MemPrev;
MemWork = MemBlock->MemPrev;
if (MemWork != NULL)
MemWork->MemNext = MemBlock->MemNext;
else
MemAnchor = MemBlock->MemNext;
Area = MemBlock->MemAddr;
Area = Area - MEMHDRLEN;
farfree(Area);
free(MemBlock);
return(0);
}
int mem_cleanup(char *Mod, int Line, char Funct)
{
char *Area;
int Ret;
MEMTBL *MemBlock, *MemWork, *Next, *Prev;
trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
Ret = mem_scan();
if (Ret)
{
mem_cancel(Line, Mod, 10+Ret, MemBlock, NULL);
return(-2);
}
MemBlock = MemAnchor;
for(;;)
{
Next = MemBlock->MemNext;
Prev = MemBlock->MemPrev;
if (MemBlock->MemFun == Funct)
{
if (Next != NULL)
Next->MemPrev = Prev;
if (Prev != NULL)
Prev->MemNext = Next;
else
MemAnchor = Next;
Area = MemBlock->MemAddr;
Area = Area - MEMHDRLEN;
farfree(Area);
free(MemBlock);
MemBlock = Next;
}
if (Next == NULL)
break;
MemBlock = Next;
}
return(0);
}
int mem_freeall(char *Mod, int Line)
{
char far *Area;
int Ret;
MEMTBL *MemBlock, *MemWork;
trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
Ret = mem_scan();
if (Ret)
{
mem_cancel(Line, Mod, 20+Ret, MemBlock, NULL);
return(-2);
}
MemBlock = MemAnchor;
for(;;)
{
Area = MemBlock->MemAddr;
Area = Area - MEMHDRLEN;
farfree(Area);
MemWork = MemBlock->MemNext;
free(MemBlock);
if (MemWork == NULL)
break;
MemBlock = MemWork;
}
MemAnchor = NULL;
return(0);
}
int mem_scan()
{
char far *Work;
MEMTBL *MemBlock, *MemWork;
trace_entry('E', "Mem", __LINE__); /* Trace Entry to Paragraph */
MemBlock = MemAnchor;
for(;;)
{
if (MemBlock == NULL)
break;
MemWork = MemBlock->MemNext;
if (MemWork != NULL)
{
if (MemWork->MemPrev != MemBlock)
{
return(1);
}
}
Work = MemBlock->MemAddr;
Work = Work - MEMHDRLEN;
if (memcmp(Work, "^MH^", MEMHDRLEN) != 0)
{
return(2);
}
Work = MemBlock->MemAddr;
Work = Work + MemBlock->MemLen;
if (memcmp(Work, "^MT^", MEMHDRLEN) != 0)
{
return(3);
}
MemBlock = MemBlock->MemNext;
}
return(0);
}
void mem_cancel(int Line, char *Mod, int Code, void far *Memory, char far *Area)
{
MEMTBL *MemBlock;
MemBlock = Memory;
MemBlock->MemOK = Code;
puts("\n\n\n\n");
puts(" [ -- ERROR -- ]\n\n");
puts(" A memory error has occurred as a result of a request");
printf(" from line %d of module %s. The error code was %d",
Line, Mod, Code);
if (Area != NULL)
printf(" The pointer to the area is %p\n", Area);
puts("\n\n\n\n");
cancel_prog(4);
}
/* ------------------------- */
/* LATrace Logic */
/* ------------------------- */
void trace_entry(char Type, char *Mod, int Line)
{
int I;
#ifdef LATRACE
if (TraceTbl == NULL)
{
TraceTbl = malloc((TRACEELEMS * sizeof(TraceTbl->TraceElem[0])) + 8);
TraceTbl->Wrap = 'N';
TraceTbl->TracePtr = 0;
}
I = TraceTbl->TracePtr;
TraceTbl->TraceElem[I].Type = Type;
strcpy(TraceTbl->TraceElem[I].Mod, Mod);
TraceTbl->TraceElem[I].Line = Line;
++TraceTbl->TracePtr;
if (TraceTbl->TracePtr > 99)
{
TraceTbl->Wrap = 'Y';
TraceTbl->TracePtr = 0;
}
#endif
return;
}
/* Dump the trace and memory information to a file names "LATrace.Lac" */
/* and end the program with the specified exit code. */
void cancel_prog(int ExitCode)
{
int Start, Curr;
FILE *TraceFile;
MEMTBL *MemBlock, *MemWork;
TraceFile = fopen("LATrace.Lac", "w");
if (TraceFile == NULL)
exit(ExitCode);
#ifdef LATRACE
fputs("----- Trace Table -----\n", TraceFile);
if (TraceTbl->Wrap == 'N')
Start = 0;
else
Start = TraceTbl->TracePtr;
Curr = Start;
for(;;)
{
fprintf(TraceFile, "T---%c---%s---%d\n",
TraceTbl->TraceElem[Curr].Type,
TraceTbl->TraceElem[Curr].Mod,
TraceTbl->TraceElem[Curr].Line);
++Curr;
if (Curr == TraceTbl->TracePtr)
break;
if (Curr > 99)
Curr = 0;
}
#endif
fputs("----- Storage -----\n", TraceFile);
MemBlock = MemAnchor;
if (MemAnchor == NULL)
fputs(" No Storage On Chain\n", TraceFile);
else
{
for(;;)
{
fprintf(TraceFile,
"M---%p---%d---%s---%d---%c---%c---%d---%p---%p---%p\n",
MemBlock,
MemBlock->MemOK,
MemBlock->MemMod,
MemBlock->MemLine,
MemBlock->MemFun,
MemBlock->MemUse,
MemBlock->MemLen,
MemBlock->MemAddr,
MemBlock->MemPrev,
MemBlock->MemNext);
MemWork = MemBlock->MemNext;
if (MemWork == NULL)
break;
MemBlock = MemWork;
}
}
fclose(TraceFile);
exit(ExitCode);
}